package com.code.refactoring.重构demo.状态机扭转.engine;

import com.code.refactoring.重构demo.状态机扭转.OrderStateEvent;
import com.code.refactoring.重构demo.状态机扭转.entity.OrderInfo;
import com.code.refactoring.重构demo.状态机扭转.entity.ServiceResult;
import com.code.refactoring.重构demo.状态机扭转.entity.StateContext;
import com.code.refactoring.重构demo.状态机扭转.stateProcessor.AbstractStateTemplateProcessor;
import com.code.refactoring.重构demo.状态机扭转.stateProcessor.StateProcessor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author wangxi03 created on 2021/4/29 2:33 下午
 * @version v1.0
 */
@Component
public class DefaultOrderFsmEngine implements OrderFsmEngine {

    @Resource
    private DefaultStateProcessRegistry stateProcessorRegistry;

    @Override
    public <T> ServiceResult<T> sendEvent(OrderStateEvent orderStateEvent) throws Exception {
        OrderInfo OrderInfo = null;
        if (orderStateEvent.newCreate()) {
            OrderInfo = getFsmOrder(orderStateEvent.getOrderId());
        }
        return sendEvent(orderStateEvent, OrderInfo);
    }

    private OrderInfo getFsmOrder(String orderId) {
        return new OrderInfo();
    }

    @Override
    public <T> ServiceResult<T> sendEvent(OrderStateEvent orderStateEvent, OrderInfo OrderInfo) throws Exception {
        // 构造当前事件上下文
        StateContext context = this.getStateContext(orderStateEvent, OrderInfo);
        // 获取当前事件处理器
        StateProcessor<T, ?> stateProcessor = this.getStateProcessor(context);
        // 执行处理逻辑
        return stateProcessor.action(context);
    }
    private <T> StateProcessor<T, ?> getStateProcessor(StateContext<?> context) {
        OrderStateEvent stateEvent = context.getOrderStateEvent();
        OrderInfo orderInfo = context.getOrderInfo();
        // 根据状态+事件对象获取所对应的业务处理器集合
        List<AbstractStateTemplateProcessor> processorList = stateProcessorRegistry.acquireStateProcess(orderInfo.getOrderState(),
                stateEvent.getEventType(), orderInfo.getBizCode(), orderInfo.getSceneId());

        return processorList.get(0);
    }
    private StateContext<?> getStateContext(OrderStateEvent orderStateEvent, OrderInfo OrderInfo) {
        StateContext<?> context = new StateContext(orderStateEvent, OrderInfo);
        return context;
    }
}
